#ifndef _MXDDEMUX_FSM_C_
#define _MXDDEMUX_FSM_C_

#undef  MODULE_NUMBER
#define MODULE_NUMBER   MODULE_TCMMB_DRV
#undef  FILE_NUMBER
#define FILE_NUMBER     5

#include "Mxddrv.h"
#include "Mxd0250API.h"
#include "Mxddemux_fsm.h"
#include "gfl.h"

//define MXD_OUTPUT_CHIPSTATUS
extern u8 cmmbdrv_frameID;
extern bool b_USER_STOP;
extern bool b_cmmbdrv_loading;
extern u8 g_mmicmmb_error;
extern MXD_HANDLE g_hMxd0250Device;
extern unsigned int gDDCWGetting;
extern MXD_BOOL g_bMxdUrgent;
extern int g_nLastServiceId;

extern bool g_bFreqLocked;
extern bool g_bTryLockFreq;
extern int cmmb_freq;
extern int chlist[];

u8 g_nLastSignal = 0;
u8 g_nNoSignalCount = 0;

extern void MMBBMS_DD_SetFinishFlag(MXD_BOOL Flag);
extern u32  demux0_3Demux(u8 *pp_Data, u32 vp_Len);
extern void Tdcmmbdrv_CmmbTrace(const char*lpszFormat, ...);
extern void  CMMBDRV_GetMtkTimer(t_FsmObject* pp_Object);

#if defined(MXD_OUTPUT_CHIPSTATUS)
extern void PrintChipStatus();
#endif

#undef PROCEDURE_NUMBER
#define PROCEDURE_NUMBER 0
void cmmb_demuxinit(void)
{
    gv_cmmbdrv_send = 0;
    gv_cmmbdrv_demux = 0;
}

void UpdateMmiSignal( int v_CMMB_signal_strength, int v_CMMB_signal_err_percent )
{
        t_CmmbdrvToMMIInd *pl_CmmbdrvToMMIInd = NULL;
        pl_CmmbdrvToMMIInd = (t_CmmbdrvToMMIInd *)MC_RTK_GET_MEMORY(sizeof(t_CmmbdrvToMMIInd));
        pl_CmmbdrvToMMIInd->v_IndType = CMMBDRV_TO_MMI_IND_TYPE_UPDATE_SIGNAL;
        pl_CmmbdrvToMMIInd->v_IndValue = v_CMMB_signal_strength;
        pl_CmmbdrvToMMIInd->v_IndValue1 = v_CMMB_signal_err_percent;
        pl_CmmbdrvToMMIInd->v_Failed = 0;
        MC_RTK_SEND_MSG_TO_PROCESS(PROCESS_CMMBDRV , 0, PROCESS_MMI, 0, CMMBDRV_TO_MMI_IND, (t_MsgHeader *)pl_CmmbdrvToMMIInd);

	MXD_DebugPrint( "update signal %d, err %d!\n", v_CMMB_signal_strength, v_CMMB_signal_err_percent );
}

#undef PROCEDURE_NUMBER
#define PROCEDURE_NUMBER 19
MXD_UINT32 tm_base;
void PirntSpendTime(int line)
{
    Tdcmmbdrv_CmmbTrace("at line %d... . spend %d\n", line, MC_DIN_TICK_TO_MS(MC_RTK_GET_TICK_COUNTER) - tm_base);
}

extern MXD_BOOL g_bMbbmsMode;
extern u16 g_bSetKeyPressFlag;
void cmmb_demux(t_FsmObject  *pp_ReceivedMsg)
{
    t_cmmb_demux_ind *pmsg = NULL;
    pmsg = (t_cmmb_demux_ind *)pp_ReceivedMsg->u_ReceivedObj.p_MessageAddress;

    MMBBMS_DD_SetFinishFlag(0);

    if (0 == pmsg->b_eb)
    {
        MXD_SYS_STATUS status;
        MXD_UINT8 reg = 0;
        Mxddrv_SuspendVpsTask();

        tm_base = MC_DIN_TICK_TO_MS(MC_RTK_GET_TICK_COUNTER);
        mbbms_drv_lock();

        if (!g_hMxd0250Device)
        {
            mbbms_drv_unlock();
            MMBBMS_DD_SetFinishFlag(1);
            return;
        }
#if defined(MXD_OUTPUT_CHIPSTATUS)
        MXD_EX_WriteReg(g_hMxd0250Device, 0xe8, 0x5d);        
        PrintChipStatus();
#endif

        MXD_EX_WriteReg(g_hMxd0250Device, 0xf8, 0);
        MXD_PulseProcess(g_hMxd0250Device);

#if 0

        if (g_nLastServiceId)
        {
            //Tdcmmbdrv_CmmbTrace( "testing urgent!!!!!!!!!!!!!!!\n" );
            MXD_EX_ReadReg(g_hMxd0250Device, 0x9, &reg);

            if (reg & 0x40)
            {
                Tdcmmbdrv_CmmbTrace("urgent occur! starting clch\n");
                MXD_OpenCLCHService(g_hMxd0250Device, NULL);
                g_bMxdUrgent = TRUE;
            }
        }

#endif

#if 1 //changed by david: 101018

	if ( g_bMbbmsMode && !g_bTryLockFreq && !g_bFreqLocked && cmmb_freq >= 13 )
	{
		MXD_DebugPrint( "Try lock freq %d again!\n", chlist[cmmb_freq-13] );
		MXD_StartServiceSearch( g_hMxd0250Device, NULL, chlist[cmmb_freq-13], chlist[cmmb_freq-13], 8, FALSE );
		g_bTryLockFreq = TRUE;
	}
	
	MXD_GetSystemStatus(g_hMxd0250Device, &status); //changed by david: 101018
	if( g_bTryLockFreq || !g_bFreqLocked || !status.bLock || (g_nLastServiceId == 0 && status.bLock && g_bFreqLocked) || status.bRecoveryStatus || status.nLdpcErrPercent > 0 )
	{
		//MXD_DebugPrint( "lock %d ldpc %d!rcy %d, g_bTryLockFreq %d, g_bFreqLocked %d, g_nLastServiceId = %d\n", status.bLock,  status.nLdpcErrPercent, status.bRecoveryStatus, g_bTryLockFreq , g_bFreqLocked , g_nLastServiceId);
		MXD_EX_WriteReg(g_hMxd0250Device, 0xf8, 32); // set chip timer
	}

	if( !g_bFreqLocked )
	{
		UpdateMmiSignal( 0, 100 );
	}
	else
	{
            int v_Signal = 0;
            int v_CMMB_signal_strength = 0;
            MXD_UINT8 nAgc;
            //read BB agc
            MXD_EX_ReadTunerReg( g_hMxd0250Device, 0x79, &nAgc);
            
            if (!status.bLock)
            {      
                v_Signal = 0;
            }
            else
            {
                if( nAgc > 0x98 )
                v_Signal = 1;
                else if( nAgc > 0x86 )
                v_Signal = 2;
                else if( nAgc >= 0x78 )
                v_Signal = 3;
                else
                v_Signal = 4;
			
                if (g_nLastServiceId != 0)
                {
                    if( status.nLdpcErrPercent > 0 && v_Signal >= 2)
                    v_Signal--;
                    if ( status.nSignalNoiseRatio < 50 )
                    v_Signal = 0;
                }
            }
            
            if (v_Signal == 0 )
            {
                if( g_nNoSignalCount++ >= 3 )
                {
                    g_nNoSignalCount = 0;
                    UpdateMmiSignal( 0, 100 );
                    g_nLastSignal = v_Signal;
                }
            }
            else 
            {
                g_nNoSignalCount = 0;
                if (v_Signal != g_nLastSignal )
                {
                    UpdateMmiSignal( v_Signal, status.nLdpcErrPercent );
                    g_nLastSignal = v_Signal;
                }
            }

		MXD_DebugPrint("\n-----signal = %d, agc=0x%x, ldpc = %d\n", v_Signal, nAgc, status.nLdpcErrPercent);
	}

#else
        /* clear all interrupt */
        MXD_EX_WriteReg(g_hMxd0250Device, 2, 0xff);
        MXD_EX_WriteReg(g_hMxd0250Device, 5, 0xff);
        MXD_EX_WriteReg(g_hMxd0250Device, 8, 0xff);
        MXD_EX_WriteReg(g_hMxd0250Device, 0xb, 0xff);
#endif

        MXD_DebugPrint("\nMXD_PulseProcess . spend %d", MC_DIN_TICK_TO_MS(MC_RTK_GET_TICK_COUNTER) - tm_base);
        //mxd_CleanInterrupt();
        mbbms_drv_unlock();

        Mxddrv_SuspendVpsTask();
    }
    else
    {
    }

    MMBBMS_DD_SetFinishFlag(1);
    Tdcmmbdrv_CmmbTrace("\r\n ---------------------------Out cmmb_demux()--------------------");
}

void cmmb_demux_msgsend(u8* pbuff, u32 size)
{
    t_cmmb_demux_ind *pmsg = NULL;
    u8* pbuff1 = NULL;
    pmsg = (t_cmmb_demux_ind *)MC_RTK_GET_MEMORY(sizeof(t_cmmb_demux_ind));

    if (NULL == pmsg)
    {
        return;
    }

    pbuff1 = (u8*)cmmbdemux_buff;
    pbuff1 += gv_cmmbdrv_send * M_DEMUX_FRAME_BUFFER_SIZE;

    if (size > M_DEMUX_FRAME_BUFFER_SIZE)
    {
        Tdcmmbdrv_CmmbTrace("---warning-----------size > M_DEMUX_FRAME_BUFFER_SIZE ");
        size = M_DEMUX_FRAME_BUFFER_SIZE;
    }

    gv_cmmbdrv_send++;

    if (gv_cmmbdrv_send == 10)
    {
        gv_cmmbdrv_send = 0;
    }

    memset(pbuff1, 0x00, M_DEMUX_FRAME_BUFFER_SIZE);
    memcpy(pbuff1, pbuff, size);
    pmsg->pdata = pbuff1;
    pmsg->v_size = size;
    pmsg->b_eb = 0;
    MC_RTK_SEND_MSG_TO_PROCESS(PROCESS_CMMBDRV , 0, PROCESS_CMMBDEMUX, 0, MAPI_CMMB_DEMUX_IND, (t_MsgHeader *)pmsg);
}

void cmmb_demux_msgsend_eb(u8* pbuff, u32 size)
{
    t_cmmb_demux_ind *pmsg = NULL;
    pmsg = (t_cmmb_demux_ind *)MC_RTK_GET_MEMORY(sizeof(t_cmmb_demux_ind));

    if (NULL == pmsg)
    {
        return;
    }

    pmsg->pdata = pbuff;
    pmsg->v_size = size;
    pmsg->b_eb = 1;
    MC_RTK_SEND_MSG_TO_PROCESS(PROCESS_CMMBDRV , 0, PROCESS_CMMBDEMUX, 0, MAPI_CMMB_DEMUX_IND, (t_MsgHeader *)pmsg);

}

void cmmb_demux_msgsend_mxd()
{
    t_cmmb_demux_ind *pmsg = NULL;
    pmsg = (t_cmmb_demux_ind *)MC_RTK_GET_MEMORY(sizeof(t_cmmb_demux_ind));

    if (NULL == pmsg)
    {
        return;
    }

    pmsg->pdata = NULL;
    pmsg->v_size = 0;
    pmsg->b_eb = 0;
    MC_RTK_SEND_MSG_TO_PROCESS(PROCESS_CMMBDRV , 0, PROCESS_CMMBDEMUX, 0, MAPI_CMMB_DEMUX_IND, (t_MsgHeader *)pmsg);
}

void cmmb_demux_msgsend_mxd2(u32 serviceId, u8* pbuff, u32 size)
{
    t_cmmb_demux_ind *pmsg = NULL;
    u8* pbuff1 = NULL;
    pmsg = (t_cmmb_demux_ind *)MC_RTK_GET_MEMORY(sizeof(t_cmmb_demux_ind));

    if (NULL == pmsg)
    {
        return;
    }

    pbuff1 = (u8*)cmmbdemux_buff;
    pbuff1 += gv_cmmbdrv_send * M_DEMUX_FRAME_BUFFER_SIZE;

    if (size > M_DEMUX_FRAME_BUFFER_SIZE)
    {
        Tdcmmbdrv_CmmbTrace("---warning-----------size > cmmbdemux_buff_size ");
        size = M_DEMUX_FRAME_BUFFER_SIZE;
    }

    gv_cmmbdrv_send++;

    if (gv_cmmbdrv_send == 10)
    {
        gv_cmmbdrv_send = 0;
    }

    memset(pbuff1, 0x00, M_DEMUX_FRAME_BUFFER_SIZE);
    memcpy(pbuff1, pbuff, size);
    pmsg->pdata = pbuff1;
    pmsg->v_size = size;
    pmsg->b_eb = serviceId;
    MC_RTK_SEND_MSG_TO_PROCESS(PROCESS_CMMBDRV , 0, PROCESS_CMMBDEMUX, 0, MAPI_CMMB_DEMUX_IND, (t_MsgHeader *)pmsg);

}

void CMMBDRV_UnknownEvent(t_FsmObject* pp_Object)
{
    if (pp_Object->v_TypeOfObj == RTK_OBJ_MESSAGE)
    {
        Tdcmmbdrv_CmmbTrace("CMMBDRV_100UnknownEvent p_MessageAddress = [0x%X]", MC_RTK_GET_MSG_OPTYPE(pp_Object->u_ReceivedObj.p_MessageAddress));
    }
    else /* RTK_OBJ_TIMER */
    {
        Tdcmmbdrv_CmmbTrace("CMMBDRV_100UnknownEvent v_TimerID = [0x%X] ", pp_Object->u_ReceivedObj.v_TimerID);
    }
}

#if defined(MXD_OUTPUT_CHIPSTATUS)
MXD_UINT8 ReadReg(MXD_UINT8 reg, MXD_UINT8 type)
{

    MXD_UINT8 regval;
    if (type == 0)
        MXD_EX_ReadReg(g_hMxd0250Device, reg, &regval);
    else
        MXD_EX_ReadTunerReg(g_hMxd0250Device, reg, &regval);
    return regval;
}

void PrintChipStatus()
{
    MXD_UINT16 rserr;
    DTP_GetRSErr(g_hMxd0250Device, &rserr);
    MXD_DebugPrint("--- rs %d, MiraReg[ 0x5f=%x, 0x2d=%x , 0x4d=%x, 0xdc=%x, 0xdd=%x, 0xe0=%x, 0xe1=%x], TunerReg[0x77=%x, 0x78=%x, 0x79=%x, 0x6d=%x ]\n", rserr, ReadReg(0x5f, 0), ReadReg(0x2d, 0), ReadReg(0x4d, 0),ReadReg(0xdc, 0), ReadReg(0xdd, 0), ReadReg(0xe0, 0), ReadReg(0xe1, 0), ReadReg(0x77, 1), ReadReg(0x78, 1), ReadReg(0x79, 1), ReadReg(0x6d, 1));
}
#endif


MC_RTK_DFSM(a_cmmb_demux_IdleState)
MC_RTK_OFSM(MAPI_CMMB_DEMUX_IND,   cmmb_demux, SAME)
MC_RTK_OFSM(OP_CMMBDRV_GET_MTK_TIMER ,   CMMBDRV_GetMtkTimer ,  SAME)
MC_RTK_FFSM(CMMBDRV_UnknownEvent,  SAME)


#undef _MXDDEMUX_FSM_C_
#endif
